import React from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';
import get from 'lodash/get';
import { useFormContext, Controller } from 'react-hook-form';

import s from './Field.module.css';

function Field({
	className,
	componentClassName,
	labelClassName,
	label,
	name,
	required,
	direction,
	silent,
	children,
	viewmode,
	hidden,
	...props
}) {
	if (viewmode) {
		const Comp = props.as;
		return (
			<div className={cn(className, s.container, s[direction])}>
				{label !== undefined && (
					<div
						className={cn(s.label, labelClassName, {
							[s.required]: required,
						})}
					>
						{label ? <span>{label}：</span> : ''}
					</div>
				)}
				<div className={s.field}>
					<Comp
						{...props}
						value={props.defaultValue}
						name={name}
						className={componentClassName}
						viewmode={viewmode}
					>
						{children}
					</Comp>
				</div>
			</div>
		);
	}

	const { control, errors } = useFormContext();
	const error = get(errors, `${name}.message`);

	return (
		<div
			className={cn(className, s.container, s[direction], {
				[s.error]: error,
				[s.hidden]: hidden,
			})}
		>
			{label !== undefined && (
				<div
					className={cn(s.label, labelClassName, { [s.required]: required })}
				>
					{label ? <span>{label}：</span> : ''}
				</div>
			)}
			<div className={s.field}>
				<Controller
					{...props}
					control={control}
					name={name}
					className={componentClassName}
				>
					{children}
				</Controller>
				{!silent && (
					<div className={cn(s.message, { [s.show]: error })}>{error}</div>
				)}
			</div>
		</div>
	);
}

Field.propTypes = {
	className: PropTypes.string,
	labelClassName: PropTypes.string,
	componentClassName: PropTypes.string,
	as: PropTypes.elementType,
	label: PropTypes.string,
	name: PropTypes.string.isRequired,
	required: PropTypes.bool,
	direction: PropTypes.oneOf(['column', 'row']),
	silent: PropTypes.bool,
	viewmode: PropTypes.bool,
	hidden: PropTypes.bool,
	defaultValue: PropTypes.any,
	children: PropTypes.node,
};
Field.defaultProps = {
	className: '',
	required: false,
	silent: false,
	viewmode: false,
	hidden: false,
};

export default Field;
